package com.xyht.medicine_management_system.modules.coupon.util;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xyht.medicine_management_system.modules.coupon.constant.CouponConstant;
import com.xyht.medicine_management_system.modules.coupon.constant.UserCouponRelationConstant;
import com.xyht.medicine_management_system.modules.coupon.entity.MmsCoupon;
import com.xyht.medicine_management_system.modules.coupon.entity.MmsUserCouponRelation;
import com.xyht.medicine_management_system.modules.coupon.entity.resp.MmsCouponResp;
import com.xyht.medicine_management_system.modules.coupon.entity.resp.MmsUserCouponRelationResp;
import com.xyht.medicine_management_system.modules.coupon.service.MmsCouponService;
import com.xyht.medicine_management_system.modules.coupon.service.MmsUserCouponRelationService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.medicine_management_system.common.util.ParamCheckUtil.isNullOrEmpty;

@Component
@Log4j2
public class CouponUtil {
    @Resource
    private MmsCouponService mmsCouponService;
    @Resource
    private MmsUserCouponRelationService mmsUserCouponRelationService;

    /**
     * 获取指定用户有效优惠券集合
     *
     * @param userId     用户id
     * @param totalPrice 商品总价,传 null 只会查出无门槛优惠券
     * @return 可用优惠券集合(查询失败返回空集合)
     */
    public List<MmsUserCouponRelationResp> getValidCouponList(String userId, BigDecimal totalPrice) {
        //构造返回数据
        List<MmsUserCouponRelationResp> mmsUserCouponRespList = new ArrayList<>();

        //当前时间
        Date nowDate = new Date();
        LambdaQueryWrapper<MmsCoupon> couponQueryWrapper = new LambdaQueryWrapper<MmsCoupon>()
                .le(MmsCoupon::getStartDate, nowDate)
                .ge(MmsCoupon::getEndDate, nowDate)
                .eq(MmsCoupon::getStatus, CouponConstant.COUPON_STATUS_AVAILABLE);
        if (totalPrice != null) {
            couponQueryWrapper.and(i -> i.eq(MmsCoupon::getType, CouponConstant.COUPON_TYPE_NO_THRESHOLD) // 无门槛
                    .or(j -> j.eq(MmsCoupon::getType, CouponConstant.COUPON_TYPE_FULL_REDUCTION) // 满减且满减金额足够
                            .le(MmsCoupon::getFullReduction, totalPrice)));
        } else {
            couponQueryWrapper.eq(MmsCoupon::getType, CouponConstant.COUPON_TYPE_NO_THRESHOLD); // 无门槛
        }
        List<MmsCoupon> couponList = mmsCouponService.list(couponQueryWrapper);
        if (couponList.isEmpty()) {
            return mmsUserCouponRespList;
        }

        //收集优惠券IdList
        List<String> couponIdList = couponList.stream().map(MmsCoupon::getId).distinct().collect(Collectors.toList());

        //查询本人是否拥有未使用的可用优惠券
        List<MmsUserCouponRelation> userCouponList = mmsUserCouponRelationService.list(new LambdaQueryWrapper<MmsUserCouponRelation>()
                .eq(MmsUserCouponRelation::getUserId, userId)
                .in(MmsUserCouponRelation::getCouponId, couponIdList)
                .eq(MmsUserCouponRelation::getIsUse, UserCouponRelationConstant.USER_COUPON_RELATION_NOT_USE)); // 未使用
        if (userCouponList.isEmpty()) {
            return mmsUserCouponRespList;
        }

        mmsUserCouponRespList = userCouponList.stream().filter(userCoupon -> {
            // 优惠券详情
            MmsCoupon coupon = mmsCouponService.getById(userCoupon.getCouponId());
            return coupon != null;
        }).map(userCoupon -> {
            MmsUserCouponRelationResp userCouponResp = new MmsUserCouponRelationResp();
            BeanUtils.copyProperties(userCoupon, userCouponResp);

            //优惠券详情
            MmsCoupon coupon = mmsCouponService.getById(userCoupon.getCouponId());
            if (!isNullOrEmpty(coupon)) {
                MmsCouponResp couponResp = new MmsCouponResp();
                BeanUtils.copyProperties(coupon, couponResp);
                userCouponResp.setCouponInfo(couponResp);
            }

            return userCouponResp;
        }).sorted(new Comparator<MmsUserCouponRelationResp>() { // 根据金额大小倒序排序
            @Override
            public int compare(MmsUserCouponRelationResp o1, MmsUserCouponRelationResp o2) {
                BigDecimal price1 = new BigDecimal(0);
                BigDecimal price2 = new BigDecimal(0);
                //设置 o1 price
                if (o1 != null) {
                    price1 = o1.getCouponInfo().getDiscountAmount();
                }
                //设置 o2 price
                if (o2 != null) {
                    price2 = o2.getCouponInfo().getDiscountAmount();
                }

                return price2.compareTo(price1); // 倒序排序
            }
        }).collect(Collectors.toList());

        return mmsUserCouponRespList;
    }

    /**
     * 获取指定用户所有优惠券集合
     *
     * @param userId 用户id
     * @return 所有优惠券集合
     */
    public List<MmsUserCouponRelationResp> getAllCouponList(String userId) {
        //构造返回数据
        List<MmsUserCouponRelationResp> mmsUserCouponRespList = new ArrayList<>();

        //查询本人是否拥有未使用的可用优惠券
        List<MmsUserCouponRelation> userCouponList = mmsUserCouponRelationService.list(new LambdaQueryWrapper<MmsUserCouponRelation>()
                .eq(MmsUserCouponRelation::getUserId, userId)
                .eq(MmsUserCouponRelation::getIsUse, UserCouponRelationConstant.USER_COUPON_RELATION_IS_USE));//未使用
        if (userCouponList.isEmpty()) {
            return mmsUserCouponRespList;
        }

        mmsUserCouponRespList = userCouponList.stream().map(userCoupon -> {
            MmsUserCouponRelationResp userCouponResp = new MmsUserCouponRelationResp();
            BeanUtils.copyProperties(userCoupon, userCouponResp);

            //优惠券详情
            MmsCoupon coupon = mmsCouponService.getById(userCoupon.getCouponId());
            if (!isNullOrEmpty(coupon)) {
                MmsCouponResp couponResp = new MmsCouponResp();
                BeanUtils.copyProperties(coupon, couponResp);
                userCouponResp.setCouponInfo(couponResp);
            }

            return userCouponResp;
        }).sorted(new Comparator<MmsUserCouponRelationResp>() {//根据满减金额大小倒序排序
            @Override
            public int compare(MmsUserCouponRelationResp o1, MmsUserCouponRelationResp o2) {
                BigDecimal price1 = new BigDecimal(0);
                BigDecimal price2 = new BigDecimal(0);
                //设置 o1 price
                if (o1.getCouponInfo().getType() == CouponConstant.COUPON_TYPE_FULL_REDUCTION) {
                    price1 = o1.getCouponInfo().getFullReduction();
                } else if (o1.getCouponInfo().getType() == CouponConstant.COUPON_TYPE_NO_THRESHOLD) {
                    price1 = o1.getCouponInfo().getDiscountAmount();
                }
                //设置 o2 price
                if (o2.getCouponInfo().getType() == CouponConstant.COUPON_TYPE_FULL_REDUCTION) {
                    price2 = o2.getCouponInfo().getFullReduction();
                } else if (o2.getCouponInfo().getType() == CouponConstant.COUPON_TYPE_NO_THRESHOLD) {
                    price2 = o2.getCouponInfo().getDiscountAmount();
                }
                return price2.compareTo(price1);//倒序排序
            }
        }).collect(Collectors.toList());

        return mmsUserCouponRespList;
    }

}
